package com.example.springsecurity.filter;

import com.example.springsecurity.pojo.Result;
import com.example.springsecurity.utils.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Map;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {//确保所有请求只过滤一次.就是拦截器
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Override//在此过滤器(拦截器)中设置拦截哪些接口，放行哪些接口
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if("/login".equals(request.getRequestURI())
                ||"/cap".equals(request.getRequestURI())
                || "/register".equals(request.getRequestURI())
                ||"/sendSms".equals(request.getRequestURI())
                ||"/test1".equals(request.getRequestURI())
                ||"/test2".equals(request.getRequestURI())
        ){
            //login,cap;register,sendSms接口直接放行
            filterChain.doFilter(request,response);//放行
            return;//确保后面不执行
        }
        String token = request.getHeader("token");
        if(token == null){
            throw  new RuntimeException("未登录（token缺失）");
        }
        //
        try {
            //从redis中获取相同的token
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            String redisToken = operations.get(token);
            if (redisToken==null) {
                //说明token已失效
                throw  new RuntimeException("未登录（token异常）");
            }
            //认证成功，则解析token
            Map<String, Object> map = JwtUtil.parseToken(token);

            //把用户信息存入安全上下文(token已经通过了校验，不需要再存密码了，只需存用户信息(id)和权限)
            Authentication authentication = new UsernamePasswordAuthenticationToken(map.get("userId"),null,null);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            //过滤器放行
            filterChain.doFilter(request,response);
            return ;//放行
        } catch (Exception e) {
            throw new RuntimeException("未登录（token异常）");
        }
    }
}
